﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection.Emit;
using System.Text;

using Xc.DataAccess.Docs.MarkDowns;

namespace Xc.DataAccess.Docs.Services
{
    /// <summary>
    /// 写入上下文
    /// </summary>
    internal class WriteContextService : IWriteContextService
    {
        /// <summary>
        /// 字符串化显示
        /// </summary>
        /// <param name="writeContext"></param>
        public static implicit operator string(WriteContextService writeContext)
        {
            return writeContext.ToString();
        }
        /// <summary>
        /// 字符串化
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Text;
        }
        StringBuilder stringBuilder = new StringBuilder();
        /// <summary>
        /// 写一行数据
        /// </summary>
        /// <param name="content"></param>
        public IWriteContextService AppendLine(params string[] content)
        {
            Write(Environment.NewLine);
            Write($"{string.Join("", content.Select(p => p.ToString()))}{Environment.NewLine}");
            Write(Environment.NewLine);
            return this;
        }
        /// <summary>
        /// 添加一行
        /// </summary>
        /// <param name="isNewLine"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public IWriteContextService AppendLine(bool isNewLine, params string[] content)
        {
            if (isNewLine)
            {
                return AppendLine(content);
            }
            else
            {
                return Append(content);
            }
        }
        /// <summary>
        /// 附加内容
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public IWriteContextService Append(params string[] content)
        {
            Write($"{string.Join("", content)}");
            return this;
        }
        /// <summary>
        /// 写数据
        /// </summary>
        /// <param name="content"></param>
        protected void Write(params string[] content)
        {
            stringBuilder.Append(string.Join("", content));
        }
        /// <summary>
        /// 刷写缓冲
        /// </summary>
        /// <returns></returns>
        public string Text => stringBuilder.ToString();
        /// <summary>
        /// 写行标题
        /// </summary>
        /// <param name="level"></param>
        /// <param name="content"></param>
        public IWriteContextService AppendHead(int level, string content)
        {
            AppendLine(Repeat("#", level), " ", content);
            return this;
        }
        /// <summary>
        /// 写行标题
        /// </summary>
        /// <param name="level"></param>
        /// <param name="callBack"></param>
        /// <returns></returns>
        public IWriteContextService AppendHead(int level, Action<IWriteContextService> callBack)
        {
            WriteContextService writeContext = new WriteContextService();
            callBack.Invoke(writeContext);
            AppendLine(Repeat("#", level), " ", writeContext.Text);
            return this;
        }
        private string Repeat(string text, int count)
        {
            var array = Enumerable.Repeat(text, count);
            return string.Join("", array);
        }
        /// <summary>
        /// 写粗体
        /// </summary>
        /// <param name="content"></param>
        public IWriteContextService AppendBold(string content)
        {
            AppendLine(false, Repeat("*", 2), content, Repeat("*", 2));
            return this;
        }
        /// <summary>
        /// 添加粗斜体
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public IWriteContextService AppendBoldItalic(string content)
        {
            AppendLine(false, Repeat("*", 3), content, Repeat("*", 3));
            return this;
        }
        /// <summary>
        /// 将数据保存到文件
        /// </summary>
        /// <param name="fileName"></param>
        public void SaveToFile(string fileName)
        {
            File.WriteAllText(fileName, stringBuilder.ToString());
        }
        /// <summary>
        /// 添加粗斜体
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public IWriteContextService AppendBoldItalicLine(string content)
        {
            AppendLine(true, Repeat("*", 3), content, Repeat("*", 3));
            return this;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public IWriteContextService AppendBoldLine(string content)
        {
            AppendLine(true, Repeat("*", 2), content, Repeat("*", 2));
            return this;
        }
        /// <summary>
        /// 写斜体
        /// </summary>
        /// <param name="content"></param>
        public IWriteContextService AppendItalic(string content)
        {
            AppendLine(false, Repeat("*", 1), content, Repeat("*", 1));
            return this;
        }
        /// <summary>
        /// 写斜体
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public IWriteContextService AppendItalicLine(string content)
        {
            AppendLine(true, Repeat("*", 1), content, Repeat("*", 1));
            return this;
        }
        /// <summary>
        /// 引用一段文字
        /// </summary>
        /// <param name="level"></param>
        /// <param name="content"></param>
        public IWriteContextService AppendRef(int level, params string[] content)
        {
            Append(Repeat(">", level), string.Join("", content)); return this;
        }
        /// <summary>
        /// 添加一行引用
        /// </summary>
        /// <param name="level"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public IWriteContextService AppendRefLine(int level, params string[] content)
        {
            List<string> vs = new List<string>();
            vs.Add(Repeat(">", level));
            vs.AddRange(content);
            AppendLine(vs.ToArray()); return this;
        }
        /// <summary>
        /// 有序列表
        /// </summary>
        public IWriteContextService AppendOrderList(int number, string content)
        {
            AppendLine(false, $"{number}.{content}.{Environment.NewLine}"); return this;
        }
        /// <summary>
        /// 无需列表
        /// </summary>
        /// <param name="prefix"></param>
        /// <param name="content"></param>
        public IWriteContextService AppendUnderOrderList(string prefix, string content)
        {
            AppendLine(false, $"{prefix} {content}.{Environment.NewLine}"); return this;
        }
        /// <summary>
        /// 写代码
        /// </summary>
        /// <param name="languange"></param>
        /// <param name="content"></param>
        public IWriteContextService AppendCode(string languange, string content)
        {
            Write(Environment.NewLine);
            Write($"``` {languange}{Environment.NewLine}");
            Write(content);
            Write(Environment.NewLine);
            Write($"```");
            return this;
        }
        /// <summary>
        /// 写代码
        /// </summary>
        /// <param name="languange"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public IWriteContextService AppendCode(string languange, Action<IWriteContextService> content)
        {
            WriteContextService writeContext = new WriteContextService();
            content.Invoke(writeContext);
            return AppendCode(languange, writeContext.ToString());
        }
        public IWriteContextService AppendCodeSimple(string code)
        {
            Write($"`{code}`"); return this;
        }
        /// <summary>
        /// 分割线
        /// </summary>
        public IWriteContextService AppendHorizontalLine()
        {
            Write($"{Repeat("*", 3)}{Environment.NewLine}"); return this;
        }
        /// <summary>
        /// 写一行
        /// </summary>
        /// <param name="title"></param>
        /// <param name="content"></param>
        /// <param name="tips">提示信息</param>
        public IWriteContextService AppendLink(string title, string content, string tips)
        {
            Write($"[{title}]({content} \"{tips}\")"); return this;
        }
        /// <summary>
        /// 写链接
        /// </summary>
        /// <param name="url"></param>
        public IWriteContextService AppendUrl(string url)
        {
            Write($"<{url}>"); return this;
        }
        /// <summary>
        /// 写文件
        /// </summary>
        /// <param name="title"></param>
        /// <param name="path"></param>
        /// <param name="tips"></param>
        public IWriteContextService AppendImage(string title, string path, string tips)
        {
            Write($"![{title}]({path} {tips})");
            return this;
        }
        /// <summary>
        /// 写表格
        /// </summary>
        /// <param name="dataTable"></param>
        public IWriteContextService AppendDataTable(MarkDataTable dataTable)
        {
            var head = string.Join("|", dataTable.Columns.Select(p => p.Text));
            Write(Environment.NewLine);
            Write(head, Environment.NewLine);
            var split = string.Join("|", dataTable.Columns.Select(p => WriteSplit(p.Aligment)));
            Write(split, Environment.NewLine);
            foreach (var item in dataTable.Rows)
            {
                var row = string.Join("|", item);
                Write(row, Environment.NewLine);
            }
            Write(Environment.NewLine);
            return this;
        }
        /// <summary>
        /// 添加一个表格
        /// </summary>
        /// <param name="dataTable"></param>
        /// <returns></returns>
        public IWriteContextService AppendDataTable(Action<MarkDataTable> dataTable)
        {
            MarkDataTable markDataTable = new MarkDataTable();
            dataTable.Invoke(markDataTable);
            return AppendDataTable(markDataTable); ;
        }
        private string WriteSplit(Aligment aligment)
        {
            if (aligment == Aligment.Left)
            {
                return $":{Repeat("-", 5)}";
            }
            else if (aligment == Aligment.Center)
            {
                return $":{Repeat("-", 5)}:";
            }
            else
            {
                return $"{Repeat("-", 5)}:";
            }
        }

        /// <summary>
        /// 写删除行
        /// </summary>
        /// <param name="content"></param>
        public IWriteContextService AppendDelete(string content)
        {
            Write("~~", content, "~~");
            return this;
        }
        /// <summary>
        /// 添加一行删除行
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public IWriteContextService AppendDeleteLine(string content)
        {
            Write(Environment.NewLine);
            AppendDelete(content);
            Write(Environment.NewLine);
            return this;
        }
        /// <summary>
        /// 写任务
        /// </summary>
        /// <param name="isCheck"></param>
        /// <param name="content"></param>
        public IWriteContextService AppendTask(bool isCheck, string content)
        {
            Write($"- [", isCheck ? "x" : " ", "]", content, Environment.NewLine);
            return this;
        }

        public IWriteContextService AppendLine(Action<IWriteContextService> callBack)
        {
            WriteContextService writeContext = new WriteContextService();
            callBack.Invoke(writeContext);
            AppendLine(writeContext.Text);
            return this;
        }
    }
}
